home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-11-06 | 9.9 KB | 361 lines | [TEXT/KAHL] |
- // ••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- // • Program: FrameAnim
- // • File: Animation.c
- // •
- // • Copyright © 1993 by Scott B. Steinman, O.D., Ph.D. All Rights Reserved.
- // ••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
-
- #include "FrameAnim.h"
-
- // • ------------------ External Globals ----------------------------------
-
- extern CWindowPtr gMainWindow; // • From Main.c file
- extern GWorldPtr gFrames[]; // • From Main.c file
- extern PicHandle gFramePICTs[]; // • From Files.c file
- extern PaletteHandle gPalette; // • From Main.c file
- extern CTabHandle gCTable; // • From Main.c file
- extern Settings gSettings; // • From Main.c file
- extern XVBLTask gXVBLTask; // • From VBlanks.c file
-
- // • ------------------ Globals -------------------------------------------
-
- Rect gGlobBounds, // • GWorld bounds in global coords
- gBounds; // • GWorld bounds in local coords
-
- // •------------------- Static Variables ----------------------------------
-
- static Rect sDrawArea, // • Regions in which to draw frames
- sTarget; // • Target square to be displayed
- static Point sOrigin, // • Origin of display window
- sCenter; // • Center of GWorld
- static short sRectSize; // • Length of target square side
- static Boolean sIncrSize; // • True=grow, false=shrink target
-
- // • ------------------ Static Functions ----------------------------------
-
- static void PlaceTargets( const short );
- static void SetDrawCoords( void );
-
- // • ------------------ Find Drawing Origin -------------------------------
-
- void
- FindOrigin( void )
- // •
- // • Find mathematical origin of the drawing window.
- {
- short v, h; // • Size of drawing window (height, width)
-
- h = gMainWindow->portRect.right - gMainWindow->portRect.left;
- v = gMainWindow->portRect.bottom - gMainWindow->portRect.top;
- SetPt( &sOrigin, h / 2, v / 2 );
- }
-
- // • ------------------ Set Drawing Coordinates ---------------------------
-
- static void
- SetDrawCoords( void )
- // •
- // • Set up drawing bounds for GWorlds and display window
- // • in local and global coordinates.
- {
- short radius;
- Point topLeft, botRight;
-
- radius = gSettings.frameSize / 2; // • Half-width of frame
-
- // • Set up drawing area in GWorlds and center point of GWorlds
-
- SetRect( &gBounds, 0, 0, gSettings.frameSize, gSettings.frameSize );
- SetPt( &sCenter, gSettings.frameSize / 2, gSettings.frameSize / 2 );
-
- // • Set local coordinates in window for GWorld copying
-
- SetRect( &sDrawArea, sOrigin.h - radius, sOrigin.v - radius,
- sOrigin.h + radius, sOrigin.v + radius );
-
- // • Convert GWorld drawing area to global screen coordinates
- // • (Used in NewGWorld for faster CopyBits operations).
-
- SetPt( &topLeft, sDrawArea.left, sDrawArea.top );
- LocalToGlobal( &topLeft );
- SetPt( &botRight, sDrawArea.right, sDrawArea.bottom );
- LocalToGlobal( &botRight );
- SetRect( &gGlobBounds, topLeft.h, topLeft.v, botRight.h, botRight.v );
- }
-
- // • ------------------ Allocate Memory for Animation Frames --------------
-
- void
- PrepareFilm( void )
- // •
- // • Initializes blocks of memory for the GWorlds to be stored.
- {
- GDHandle currentDev = NullHandle;
- CGrafPtr currentPort = NullPointer;
- QDErr qderror;
- short i;
- Str255 errStr;
-
- GetGWorld( ¤tPort, ¤tDev ); // • Save current port & device
- UpdateWindowColors(); // • Ensure palette is current
-
- // • Free any previously-allocated animation frame GWorlds.
-
- DisposeFrames();
-
- // • Set bounds for drawing into GWorlds and window.
-
- SetDrawCoords();
-
- // • Allocate space on heap for new GWorlds.
-
- qderror = NewGWorld( &gFrames[ 0 ], 0, &gGlobBounds, NullHandle,
- NullHandle, (GWorldFlags) NoFlags );
- if (qderror != noErr) {
- ErrNumToPstr( qderror, (char *) errStr );
- ErrorHandler( kNoGWorldMsg, (char *) "\pErrorCode = ",
- (char *) errStr, (char *) NilString );
- }
- if (gFrames[ 0 ] == NullPointer)
- ErrorHandler( kNoMemoryMsg, (char *) NilString,
- (char *) NilString, (char *) NilString );
-
- // • Move GWorld PixMaps to top of heap to maximize contiguous memory.
-
- MoveHHi( (Handle) GetGWorldPixMap( gFrames[ 0 ] ) );
-
- // • Prevent freeing of PixMap memory until we're ready.
-
- NoPurgePixels( GetGWorldPixMap( gFrames[ 0 ] ) );
-
- // • Get as much contiguous heap space for the GWorlds as possible.
-
- MaximizeHeap( (GetPtrSize( gFrames[ 0 ] ) +
- GetHandleSize( GetGWorldPixMap( gFrames[ 0 ] ) )) * kMaxFrames );
-
- for (i = 1; i < gSettings.numFrames; i++) {
- qderror = NewGWorld( &gFrames[ i ], 0, &gGlobBounds, NullHandle,
- GetGWorldDevice( gFrames[ 0 ] ), noNewDevice );
- if (qderror != noErr) {
- ErrNumToPstr( qderror, (char *) errStr );
- ErrorHandler( kNoGWorldMsg, (char *) "\pErrorCode = ",
- (char *) errStr, (char *) NilString );
- }
- if (gFrames[ i ] == NullPointer)
- ErrorHandler( kNoMemoryMsg, (char *) NilString,
- (char *) NilString, (char *) NilString );
- MoveHHi( (Handle) GetGWorldPixMap( gFrames[ i ] ) );
- NoPurgePixels( GetGWorldPixMap( gFrames[ i ] ) );
- }
-
- SetGWorld( currentPort, currentDev ); // • Restore port & device
- UpdateGWorldColors();
- }
-
- // • ------------------ Plot Targets in Frames ----------------------------
-
- static void
- PlaceTargets( const short frm )
- // •
- // • Draws rectangle target inside frame for demonstrating animation.
- {
- RGBColor rgbTarget, rgbBkgnd;
-
- if (sIncrSize) {
- sRectSize += gSettings.sizeDiff;
- if (sRectSize >= gSettings.frameSize - 10) {
- sRectSize -= gSettings.sizeDiff * 2;
- sIncrSize = false;
- }
- }
- else {
- sRectSize -= gSettings.sizeDiff;
- if (sRectSize <= 0) {
- sRectSize += gSettings.sizeDiff * 2;
- sIncrSize = true;
- }
- }
- SetRect( &sTarget, sCenter.h - (sRectSize / 2),
- sCenter.v - (sRectSize / 2), sCenter.h + (sRectSize / 2),
- sCenter.v + (sRectSize / 2) );
-
- // • Draw target in offscreen GWorld
-
- PenSize( 2, 2 ); // • Set outline width for target rectangle.
-
- PmForeColor( kPalBkgnd ); // • Clear background
- PaintRect( &gBounds );
-
- PmForeColor( kPalTarget ); // • Draw rectangle outline
- FrameRect( &sTarget );
-
- ResetForeAndBackColors();
-
- // • Get background and target colors
-
- GetEntryColor( gPalette, kPalBkgnd, &rgbBkgnd );
- GetEntryColor( gPalette, kPalTarget, &rgbTarget );
-
- // • Repeat drawing into PICT for saving to file.
- // • Use Color Mgr routines instead of Palette Mgr!
-
- gFramePICTs[ frm ] = OpenPicture( &gBounds );
-
- PenSize( 2, 2 );
- RGBForeColor( &rgbBkgnd );
- PaintRect( &gBounds );
- RGBForeColor( &rgbTarget );
- FrameRect( &sTarget );
-
- ClosePicture();
-
- ResetForeAndBackColors();
- }
-
- // • ------------------ Record the Frames into a Film Sequence ------------
-
- void
- DoFilm( void )
- // •
- // • Records the frames which are later shown with PlayFilm.
- {
- GDHandle currentDev = NullHandle;
- CGrafPtr currentPort = NullPointer;
- short i;
-
-
- sRectSize = 0;
- sIncrSize = true;
-
- PrepareFilm(); // • Allocate film storage.
-
- GetGWorld( ¤tPort, ¤tDev ); // • Save current port & device
- for (i = 0; i < gSettings.numFrames; i++) {
-
- // • Draw frame area directly into GWorld
-
- LockPixels( GetGWorldPixMap( gFrames[ i ] ) );
- SetGWorld( gFrames[ i ], NullPointer );
- PlaceTargets( i );
- SetGWorld( currentPort, currentDev ); // • Reset port & device
- UnlockPixels( GetGWorldPixMap( gFrames[ i ] ) );
- ResetForeAndBackColors();
- }
- SysBeep( 1 );
- }
-
- // • ------------------ Show Recorded Animation Sequence ------------------
-
- void
- PlayFilm( void )
- // •
- // • Play a pre-recorded animation sequence.
- {
- long finalTicks;
- short i;
-
- ResetForeAndBackColors();
- HideCursor(); // • Get cursor out of the way
-
- for (i = 0; i < gSettings.numFrames; i++)
- LockPixels( GetGWorldPixMap( gFrames[ i ] ) );
-
- // • Insert our VBlank task into interrupt queue.
-
- SetUpVBlankAnimation();
-
- // • Allow VBlank task to execute.
-
- gXVBLTask.vbl.vblCount = 1;
-
- // • Once per VBlank, copy a frame to the screen.
-
- while (gXVBLTask.frameIndex < gSettings.numFrames) {
- if (gXVBLTask.showFrame == true) {
- gXVBLTask.showFrame = false;
- CopyBits( &gFrames[ gXVBLTask.frameIndex ]->portPixMap,
- &gMainWindow->portPixMap, &gBounds, &sDrawArea, srcCopy,
- NullHandle );
- }
- }
-
- // • Remove VBlank task from interrupt queue.
-
- ShutDownVBlankAnimation();
-
- for (i = 0; i < gSettings.numFrames; i++)
- UnlockPixels( GetGWorldPixMap( gFrames[ i ] ) );
-
- // • Clear the screen when finished.
-
- Delay( 5, &finalTicks );
- PmForeColor( kPalBkgnd );
- PaintRect( &(gMainWindow->portRect) ); // • Clear window background
- ResetForeAndBackColors();
- ShowCursor(); // • Put the cursor back out
- }
-
- // • ------------------ Update Frame GWorld Palettes ----------------------
-
- void
- UpdateGWorldColors( void )
- // •
- // • Sets gray levels of GWorlds.
- {
- GDHandle currentDev = NullHandle;
- CGrafPtr currentPort = NullPointer;
- short i;
-
- GetGWorld( ¤tPort, ¤tDev ); // • Save current port & device
- for (i = 0; i < gSettings.numFrames; i++) {
- if (gFrames[ i ] != NullPointer) {
- SetGWorld( gFrames[ i ], NullPointer );
- NSetPalette( (WindowPtr) gFrames[ i ], gPalette, true );
- ActivatePalette( (WindowPtr) gFrames[ i ] );
- }
- }
- SetGWorld( currentPort, currentDev ); // • Restore port & device
- }
-
- // • ------------------ Dispose of the Frame GWorlds ----------------------
-
- void
- DisposeFrames( void )
- // •
- // • Dispose of the animation frame GWorlds.
- {
- short i;
-
- for (i = 0; i < kMaxFrames; i++) {
- if (gFrames[ i ] != NullPointer) {
- DisposeGWorld( gFrames[ i ] );
- gFrames[ i ] = NullPointer;
- }
- }
- }
-
- // • ------------------ Reset Foreground & Background Colors --------------
-
- void
- ResetForeAndBackColors( void )
- {
- PmForeColor( kPalBlack );
- PmBackColor( kPalWhite );
- }
-
- // • ------------------ Round Up a Number ---------------------------------
-
- short
- RoundUp( const double inputNumber )
- // •
- // • Rounds up a floating-point number into next highest whole integer.
- {
- short wholeNumber, roundNumber;
-
- wholeNumber = (short) inputNumber;
- if (inputNumber - wholeNumber == 0.0)
- return( wholeNumber );
- else
- return( wholeNumber + 1 );
- }
-